package com.wxxymaker.utils;

import com.blade.Blade;
import com.blade.Environment;
import com.blade.mvc.WebContext;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.github.biezhi.anima.Anima;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;

/**
 * @AUTHOR soft
 * @DATE 2018/8/12 1:30
 * @DESCRIBE 初始化配置工具
 */
@Slf4j
public class ConfigUtils {
    /**
     * 判断是否已经初始化
     * @return 初始化U状态
     */
    public static boolean isInit() {
        Boolean isInit = (Boolean) SimpleCache.get(Const.lockKey);
        if (null == isInit || !isInit) {
            File lock = new File(Const.CLASSPATH, "static/.lock");
            return lock.exists();
        }
        return true;
    }

    /**
     * 根据配置自动初始化数据库信息
     * @param config 配置 包括基本的配置信息
     * @return 成功与否
     */
    public static boolean init(Config config) {
        boolean result = false;
        Blade blade = WebContext.blade();
        Environment ev = blade.environment();

        if ("mysql".equals(config.getDbType())) {
            config.setDbUrl("jdbc:mysql://" + config.getDbUrl() +
                    "/cklab?useUnicode=true&characterEncoding=UTF-8");
            result = initMysql(config);
        } else {
            config.setDbUrl(ev.get("sqlite.jdbcUrl", "jdbc:sqlite:cklab.db"));
            result = initSqlite(config);
        }
        if (result && addLock()) {
            openSQL(ev, config);
            SimpleCache.set(Const.configKey, config);
        }
        return result;
    }

    /**
     * 初始化打开数据库
     * @param ev  blade环境
     * @param config 配置信息
     */
    public static void openSQL(Environment ev, Config config) {
        Properties properties = new Properties();
        properties.putAll(ev.getPrefix(config.getDbType()));
        HikariConfig hikariConfig = new HikariConfig(properties);
        hikariConfig.setJdbcUrl(config.getDbUrl());
        if ("mysql".equals(config.getDbType())) {
            hikariConfig.setUsername(config.getDbName());
            hikariConfig.setPassword(config.getDbPass());
        }
        HikariDataSource dataSource = new HikariDataSource(hikariConfig);
        Anima.open(dataSource);
    }

    /**
     * 添加初始化锁 有锁表示初始化过
     * @return 是否加锁成功
     */
    private static boolean addLock() {
        File lock = new File(Const.CLASSPATH, "static/.lock");
        try {
            if (lock.createNewFile()) {
                SimpleCache.set(Const.lockKey, true);
                return true;
            }
        } catch (IOException e) {
            log.error("加锁文件创建失败！{}", e.getMessage());
        }
        return false;
    }

    private static boolean initMysql(Config config) {
        String cAdmin = "CREATE TABLE IF NOT EXISTS `admin` (\n" +
                "  `id` int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "  `name` varchar(55) DEFAULT NULL,\n" +
                "  `pass` varchar(55) DEFAULT NULL,\n" +
                "  `views` int(11) unsigned DEFAULT '0'\n" +
                ") ENGINE=InnoDB";
        String cImgMapping = "CREATE TABLE IF NOT EXISTS art_image(\n" +
                "    id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "    flag_key VARCHAR(55),\n" +
                "    path VARCHAR(55)\n" +
                ") ENGINE=INNODB";
        String cArticle = "CREATE TABLE IF NOT EXISTS article (\n" +
                "  id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "  type VARCHAR(11),\n" +
                "  title VARCHAR(255),\n" +
                "  intro text,\n" +
                "  time datetime,\n" +
                "  status INT(1) DEFAULT 0,\n" +
                "  views INT(11) DEFAULT 0,\n" +
                "  likes INT(11) DEFAULT 0,\n" +
                "  path VARCHAR(100),\n" +
                "  photo VARCHAR(100), \n" +
                "  flag_key VARCHAR(55) NULL\n" +
                ") ENGINE=INNODB";
        String cEmail = "CREATE TABLE IF NOT EXISTS email (\n" +
                "  id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "  name VARCHAR(32) DEFAULT NULL,\n" +
                "  email VARCHAR(32) DEFAULT NULL,\n" +
                "  time DATETIME DEFAULT NULL,\n" +
                "  status INT(1) DEFAULT 0,\n" +
                "  content TEXT,\n" +
                "  tel VARCHAR(15),\n" +
                "  sex INT(1)\n" +
                ")ENGINE=INNODB";
        String cMember = "CREATE TABLE IF NOT EXISTS `member` (\n" +
                "  `id`    int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "  `name`  VARCHAR(40) DEFAULT NULL,\n" +
                "  `sex`   VARCHAR(10) DEFAULT NULL,\n" +
                "  `grade` VARCHAR(128) DEFAULT NULL,\n" +
                "  `tel`   VARCHAR(15) DEFAULT NULL,\n" +
                "  `birth` VARCHAR(32) DEFAULT NULL\n" +
                ", qq VARCHAR(13) NULL\n" +
                ")ENGINE=INNODB";
        String cVisitor = "CREATE TABLE IF NOT EXISTS visitor (\n" +
                "  id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,\n" +
                "  time VARCHAR(55),\n" +
                "  location VARCHAR(55),\n" +
                "  ip VARCHAR(55)\n" +
                ") ENGINE=INNODB";
        try {
            String jdbcUrl = config.getDbUrl();
            int index = jdbcUrl.indexOf("?");
            String db = jdbcUrl.substring(jdbcUrl.lastIndexOf("/") + 1);
            if (index != -1) {
                db = jdbcUrl.substring(jdbcUrl.lastIndexOf("/") + 1, index);
            }
            String mysql = "jdbc:mysql://" + config.getDbUrl() + "/mysql";
            Anima.open(mysql, config.getDbName(), config.getDbPass());
            Anima.execute("CREATE DATABASE IF NOT EXISTS " + db + " DEFAULT CHARSET utf8");
            Anima.open(jdbcUrl, config.getDbName(), config.getDbPass());

            for (String sql : Arrays.asList(cAdmin, cArticle, cEmail,
                    cImgMapping, cMember, cVisitor)) {
                Anima.execute(sql);
            }

            Anima.execute("insert into admin (name, pass)values(?, ?)", config.getUsername(),
                    config.getPassword());
        } catch (Exception e) {
            log.error("初始化数据库失败！{}", e.getMessage());
            return false;
        }
        return true;
    }

    private static boolean initSqlite(Config config) {
        String createAdmin = "CREATE TABLE IF NOT EXISTS \"admin\" (\n" +
                "  \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"name\" VARCHAR(55) NOT NULL,\n" +
                "  \"pass\" VARCHAR(55) NOT NULL,\n" +
                "  \"views\" INT NOT NULL DEFAULT 0\n" +
                ")";
        String createImgMapping = "CREATE TABLE IF NOT EXISTS \"art_image\" (\n" +
                "  \"id\" INTEGER PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"flag_key\" VARCHAR(55),\n" +
                "  \"path\" VARCHAR(55)\n" +
                ")";
        String createArticle = "CREATE TABLE IF NOT EXISTS \"article\" (\n" +
                "  \"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"type\" text(11),\n" +
                "  \"title\" text(255),\n" +
                "  \"intro\" text,\n" +
                "  \"time\" datetime,\n" +
                "  \"status\" integer(1) DEFAULT 0,\n" +
                "  \"views\" integer(11) DEFAULT 0,\n" +
                "  \"likes\" integer(11) DEFAULT 0,\n" +
                "  \"path\" text(100),\n" +
                "  \"photo\" text(100),\n" +
                "  \"flag_key\" VARCHAR(55)\n" +
                ")";
        String createEmail = "CREATE TABLE IF NOT EXISTS \"email\" (\n" +
                "  \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"name\" VARCHAR(32) DEFAULT NULL,\n" +
                "  \"email\" VARCHAR(32) DEFAULT NULL,\n" +
                "  \"time\" DATETIME DEFAULT NULL,\n" +
                "  \"status\" INT(1) DEFAULT 0,\n" +
                "  \"content\" TEXT,\n" +
                "  \"tel\" VARCHAR(15),\n" +
                "  \"sex\" INT\n" +
                ")";
        String createMember = "CREATE TABLE IF NOT EXISTS \"member\" (\n" +
                "  \"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"name\" VARCHAR(40) DEFAULT NULL,\n" +
                "  \"sex\" VARCHAR(10) DEFAULT NULL,\n" +
                "  \"grade\" VARCHAR(128) DEFAULT NULL,\n" +
                "  \"tel\" VARCHAR(15) DEFAULT NULL,\n" +
                "  \"birth\" VARCHAR(32) DEFAULT NULL,\n" +
                "  \"qq\" VARCHAR(13)\n" +
                ")";
        String createVisitor = "CREATE TABLE IF NOT EXISTS \"visitor\" (\n" +
                "  \"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
                "  \"time\" VARCHAR(55),\n" +
                "  \"location\" VARCHAR(55),\n" +
                "  \"ip\" VARCHAR(55)\n" +
                ")";
        try {
            Anima.open(config.getDbUrl());
            for (String sql : Arrays.asList(createAdmin, createArticle,
                    createEmail, createImgMapping,
                    createMember, createVisitor)) {
                Anima.execute(sql);
            }

            Anima.execute("insert into admin (name, pass)values(?, ?)", config.getUsername(),
                    config.getPassword());
        } catch (Exception e) {
            log.error("初始化数据库失败！{}", e.getMessage());
            return false;
        }
        return true;
    }
}
